#include "gwcommandline.h"
#include "boost/tokenizer.hpp"

using namespace gwBedrockApp;

char gwCommandLine::m_strOpitionNotFound[]  = "Option not found!";
char gwCommandLine::m_strOptionRequire[]    = "Option require!";

typedef boost::char_separator<char>   gwSeparatorFunc;

typedef boost::tokenizer<
                          gwSeparatorFunc,
                          std::string::const_iterator,
                          std::string
                        > gwTokenizer;

/***************************************************************************************************************************/
std::string
gwCommandLine::ConvertCmdArgToString(int argc, char **argv)
{
        std::string  options;
        for(int i = 0 ; i < argc; ++i)
        {
                options = options + "\t" + argv[i];
        }

        return options;
}

/***************************************************************************************************************************/
gwCommandLine::gwCommandLine():
m_pcLastErrror(gwNULL),
m_iArgNum(0)
{

}

/***************************************************************************************************************************/
gwCommandLine::gwCommandLine(int argc, char **argv):
m_pcLastErrror(gwNULL),
m_iArgNum(argc)
{
        if(argc > 0)
        {
               std::string cmdLine = ConvertCmdArgToString(argc, argv);
               gwSeparatorFunc      separator("-\t");
               gwTokenizer          token(cmdLine,separator);

	       int size = 0;
                //separate the string
               for(gwTokenizer::iterator itr = token.begin() ; itr != token.end() ; ++itr)
               {
				        m_ArgArray.push_back(*itr);
				        ++size;
               }

		       m_iArgNum = (size - 1) / 2;
        }
}

/***************************************************************************************************************************/
gwCommandLine::gwCommandLine(const std::string& cmdLine):
m_pcLastErrror(gwNULL),
m_iArgNum(0)
{
        gwSeparatorFunc      separator("-\t");
        gwTokenizer          token(cmdLine,separator);

	int size = 0;
        //separate the string
        for(gwTokenizer::iterator itr = token.begin() ; itr != token.end() ; ++itr)
        {
                m_ArgArray.push_back(*itr);
		++size;
        }

	m_iArgNum = (size - 1) / 2;
}

/***************************************************************************************************************************/
gwCommandLine::gwCommandLine(const gwCommandLine& rhs):
m_pcLastErrror(gwNULL),
m_iArgNum(rhs.m_iArgNum),
m_ArgArray(rhs.m_ArgArray)
{

}

/***************************************************************************************************************************/
gwCommandLine::~gwCommandLine()
{
  if(m_ArgArray.size() > 0)
    m_ArgArray.clear();
}

/***************************************************************************************************************************/
int
gwCommandLine::FindIndex(const std::string& option)
{
        if(m_ArgArray.size() > 0)
        {
                unsigned int max_index = m_ArgArray.size();
                for(unsigned int i = 0 ; i < max_index; ++i)
                {
                        m_pcLastErrror = gwNULL;
                        if(m_ArgArray[i] == option)
                                return i + 1;
                }

                m_pcLastErrror = m_strOpitionNotFound;
        }
        else
                m_pcLastErrror = m_strOptionRequire;


        return gwInvalidIndex;
}

/***************************************************************************************************************************/
bool
gwCommandLine::GetBool(const std::string &Option, bool defaultValue)
{
        int index = FindIndex(Option);
        if(index != gwInvalidIndex)
                return m_ArgArray[index].AsBoolen();

        return defaultValue;
}

/***************************************************************************************************************************/
int
gwCommandLine::GetInt(const std::string &Option, int defaultValue)
{
        int index = FindIndex(Option);
        if(index != gwInvalidIndex)
                return m_ArgArray[index].AsInt();

        return defaultValue;
}

/***************************************************************************************************************************/
float
gwCommandLine::GetFloat(const std::string &Option, float defaultValue)
{
        int index = FindIndex(Option);
        if(index != gwInvalidIndex)
                return m_ArgArray[index].AsFloat();

        return defaultValue;
}

/***************************************************************************************************************************/
std::string
gwCommandLine::GetString(const std::string &Option, const std::string &defaultValue)
{
        int index = FindIndex(Option);
        if(index != gwInvalidIndex)
                return m_ArgArray[index].AsString();

        return defaultValue;
}

/***************************************************************************************************************************/
bool
gwCommandLine::GetBoolByIndex(unsigned int index, bool defaultValue)
{
        if(index <= m_ArgArray.size() - 1)
                return m_ArgArray[index].AsBoolen();

        return defaultValue;
}

/***************************************************************************************************************************/
int
gwCommandLine::GetIntByIndex(unsigned int index, int defaultValue)
{
        if(index <= m_ArgArray.size() - 1)
                return m_ArgArray[index].AsInt();

        return defaultValue;
}

/***************************************************************************************************************************/
float
gwCommandLine::GetFloatByIndex(unsigned int index, float defaultValue)
{
        if(index <= m_ArgArray.size() - 1)
                return m_ArgArray[index].AsFloat();

        return defaultValue;
}

/***************************************************************************************************************************/
std::string
gwCommandLine::GetStringByIndex(unsigned int index, const std::string &defaultValue)
{
        if(index <= m_ArgArray.size() - 1)
                return m_ArgArray[index].AsString();

        return defaultValue;
}

/***************************************************************************************************************************/
gwCommandLine&
gwCommandLine::operator =(const gwBedrockApp::gwCommandLine &rhs)
{
        m_iArgNum = rhs.m_iArgNum;
        m_ArgArray = rhs.m_ArgArray;
        return *this;
}
